home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / source / blt / blt.c next >
Encoding:
C/C++ Source or Header  |  1994-02-28  |  54.2 KB  |  1,899 lines

  1. #include <windows.h>
  2. #include <windowsx.h>
  3. #include <commdlg.h>
  4. #include <mmsystem.h>   // for timeGetTime()
  5. #include <stdlib.h>     // for rand()
  6. #include "blt.h"
  7. #include "dib.h"
  8.  
  9. #ifndef DIB_PAL_INDICES
  10. #define DIB_PAL_INDICES 2
  11. #endif
  12.  
  13. #ifdef WIN32
  14.     // unless you have Win32s 1.1 timeGetTime() does not work
  15. //  #define timeGetTime()   GetTickCount()
  16. #endif
  17.  
  18. /*----------------------------------------------------------------------------*\
  19. \*----------------------------------------------------------------------------*/
  20.  
  21. #define DIB_TYPE_555     100
  22. #define DIB_TYPE_565     101
  23. #define DIB_TYPE_RGB     102
  24. #define DIB_TYPE_BGR     103
  25.  
  26. static PDIB MakeDib(int bits, int dx, int dy, UINT type);
  27.  
  28. /*----------------------------------------------------------------------------*\
  29. \*----------------------------------------------------------------------------*/
  30. char    szAppName[]="Blt App";
  31. char    szAppFilter[]="Bitmaps\0*.bmp;*.dib\0All Files\0*.*\0";
  32.  
  33. HINSTANCE hInstApp;
  34. HWND      hwndApp;
  35. HACCEL    hAccelApp;
  36. HPALETTE  hpalApp;
  37. HPALETTE  hpalBack;
  38. HRGN      hrgnClip;
  39. BOOL      fAppActive;
  40. BOOL      gfBackPal;
  41. BOOL      gfIdentPal=TRUE;
  42. BOOL      gfClipping;
  43. BOOL      gfStretch;
  44. BOOL      gfMirror;
  45.  
  46. #ifdef WIN32
  47.     #define _export
  48.     #define _huge
  49. #else
  50.     #define SetPixelV   SetPixel
  51. #endif
  52.  
  53. struct {
  54.     BITMAPINFOHEADER bi;
  55.     RGBQUAD          argb[256];
  56. }   biRgb;
  57.  
  58. struct {
  59.     BITMAPINFOHEADER bi;
  60.     WORD             aw[512];
  61. }   biPal;
  62.  
  63. struct {
  64.     BITMAP bm;
  65.     BITMAPINFOHEADER bi;
  66. }   ds;
  67.  
  68. LPBITMAPINFOHEADER lpbiApp;
  69. HBITMAP hbmApp;
  70. HBITMAP hbmDS;           // from CreateDIBSection
  71. HBITMAP hbmMono;
  72. HDC     hdcApp;
  73. HDC     hdcDS;
  74. int     ScreenDepth;
  75. int     TestSize = 100;
  76. int     TestSign = 1;
  77.  
  78. BITMAP  bm;
  79. DWORD   SizeImage;
  80. DWORD   OffsetScan0;
  81. LPBYTE  lpBitmapBits;
  82. LPVOID  lpDibBits;
  83. LPBYTE  BitmapTranslate;
  84.  
  85. typedef void (*PDraw)(HDC hdc, int x, int y, int dx, int dy);
  86.  
  87. void DrawRGB(HDC hdc, int x, int y, int dx, int dy);
  88. void DrawPAL(HDC hdc, int x, int y, int dx, int dy);
  89. void DrawIDX(HDC hdc, int x, int y, int dx, int dy);
  90.  
  91. void DrawDRGB(HDC hdc, int x, int y, int dx, int dy);
  92. void DrawDPAL(HDC hdc, int x, int y, int dx, int dy);
  93. void DrawDIDX(HDC hdc, int x, int y, int dx, int dy);
  94.  
  95. void DrawBLTDS(HDC hdc, int x, int y, int dx, int dy);
  96. void DrawBLT(HDC hdc, int x, int y, int dx, int dy);
  97. void DrawSBDS(HDC hdc, int x, int y, int dx, int dy);
  98. void DrawSB(HDC hdc, int x, int y, int dx, int dy);
  99. void DrawDEV(HDC hdc, int x, int y, int dx, int dy);
  100. void DrawXLATBLT(HDC hdc, int x, int y, int dx, int dy);
  101. void DrawCOPYBLT(HDC hdc, int x, int y, int dx, int dy);
  102.  
  103. void DoSetBitmapBitsBitBlt(HDC hdc, int x, int y, int dx, int dy);
  104. void DoSetDIBitsPalBitBlt(HDC hdc, int x, int y, int dx, int dy);
  105. void DoSetDIBitsRgbBitBlt(HDC hdc, int x, int y, int dx, int dy);
  106.  
  107. void DrawDVA(HDC hdc, int x, int y, int dx, int dy);
  108. BOOL InitDVA(void);
  109.  
  110. void DrawDDI(HDC hdc, int x, int y, int dx, int dy);
  111. BOOL InitDDI(void);
  112.  
  113. void DoSetDIBitsPal(HDC hdc, int x, int y, int dx, int dy);
  114. void DoSetDIBitsRgb(HDC hdc, int x, int y, int dx, int dy);
  115.  
  116. void DoGetDIBitsPal(HDC hdc, int x, int y, int dx, int dy);
  117. void DoGetDIBitsRgb(HDC hdc, int x, int y, int dx, int dy);
  118.  
  119. BOOL InitYES()  {return TRUE;}
  120. void DrawNull(HDC hdc, int x, int y, int dx, int dy) {}
  121.  
  122. BOOL IsWin32s()
  123. {
  124.     return LOBYTE(GetVersion()) == 3 && (GetVersion() & 0x80000000l);
  125. }
  126.  
  127. BOOL IsWin32c()
  128. {
  129.     return LOBYTE(GetVersion()) >= 4 && (GetVersion() & 0x80000000l);
  130. }
  131.  
  132. //
  133. // are we able to use DIB_PAL_INDICES
  134. //
  135. BOOL InitIDX()  {return !IsWin32s() && !IsWin32c();}
  136.  
  137. //
  138. // stuff to test CreateDIBSection
  139. //
  140. static HBITMAP (WINAPI *XCreateDIBSection)(HDC, LPBITMAPINFO, UINT, LPVOID FAR *, DWORD, DWORD);
  141. #define CreateDIBSection XCreateDIBSection
  142.  
  143. #ifdef WIN32
  144.     #define GDIMOD    "GDI32"
  145. #else
  146.     #define GDIMOD     "GDI"
  147. #endif
  148.  
  149. static BOOL InitDS()
  150. {
  151.     (FARPROC&)XCreateDIBSection = GetProcAddress(GetModuleHandle(GDIMOD), "CreateDIBSection");
  152.  
  153.         if (hbmApp)
  154.             return hbmDS != NULL;
  155.  
  156.         return XCreateDIBSection != NULL;
  157. }
  158.  
  159. static UINT     RandomSeed;
  160.  
  161. struct {
  162.     PDraw Draw;
  163.     BOOL (*Init)(void);
  164.     char *      szName;
  165.     LONG        time;
  166.     DWORD       pps[20];    // pixels per second
  167.     int         count;
  168. }   aDraw[] = {
  169.     //
  170.     // BitBlt and StretchBlt for comparing.
  171.     //
  172.         {DrawBLT,NULL,    "BitBlt"},
  173.         {DrawSB, NULL,    "StretchBlt"},
  174.         {NULL},
  175.  
  176.     //
  177.     // CreateDIBSection.
  178.     //
  179.         {DrawBLTDS, InitDS,  "BitBlt (DIBSection)"},
  180.         {DrawSBDS,  InitDS,  "StretchBlt (DIBSection)"},
  181.         {NULL},
  182.  
  183.     //
  184.     //    SetDIBitsToDevice
  185.     //
  186.         {DrawRGB,NULL,    "DibToDevice (RGB)"},
  187.         {DrawPAL,NULL,    "DibToDevice (PAL)"},
  188. #ifdef WIN32
  189.         {DrawIDX,InitIDX, "DibToDevice (IDX)"},
  190. #endif
  191.         {NULL},
  192.  
  193.     //
  194.     //    StretchDIBits, should be the same 
  195.     //
  196.         {DrawDRGB,NULL,   "StretchDIBits (RGB)"},
  197.         {DrawDPAL,NULL,   "StretchDIBits (PAL)"},
  198. #ifdef WIN32
  199.         {DrawDIDX,InitIDX,"StretchDIBits (IDX)"},
  200. #endif
  201.         {NULL},
  202.  
  203.     //
  204.     // versions of set+BitBlt
  205.         //
  206. #if 0
  207. #ifndef WIN32
  208.         //  uses .ASM code
  209.         {DrawXLATBLT,NULL,"XlatBits + BitBlt"},
  210.         {DrawCOPYBLT,NULL,"CopyBits + BitBlt"},
  211. #endif
  212. #endif
  213.         {DoSetBitmapBitsBitBlt,NULL, "SetBitmapBits + BitBlt"},
  214.         {DoSetDIBitsPalBitBlt,NULL,  "SetDIBits(PAL) + BitBlt"},
  215.         {DoSetDIBitsRgbBitBlt,NULL,  "SetDIBits(RGB) + BitBlt"},
  216.         {NULL},
  217.  
  218. #if 0
  219.         //
  220.         //  to test the speed of these.
  221.         //
  222.         {DoGetDIBitsRgb,NULL, "GetDIBits (RGB)"},
  223.         {DoGetDIBitsPal,NULL, "GetDIBits (PAL)"},
  224.         NULL, NULL, NULL, 0, 0,
  225.  
  226.         {DoSetDIBitsRgb,NULL, "SetDIBits (RGB)"},
  227.         {DoSetDIBitsPal,NULL, "SetDIBits (PAL)"},
  228.         {NULL},
  229. #endif
  230.  
  231. #ifndef WIN32
  232.     //
  233.         // DVA
  234.         //
  235.         {DrawDVA,InitDVA, "Direct Access"},
  236.  
  237.     //
  238.         // DDI
  239.         //
  240.         {DrawDDI,InitDDI, "OEMBitBlt"},
  241. #endif
  242. };
  243.  
  244. #define NUM_DRAW    (sizeof(aDraw) / sizeof(aDraw[0]))
  245.  
  246. /*----------------------------------------------------------------------------*\
  247. \*----------------------------------------------------------------------------*/
  248.  
  249. static int iDraw;
  250. static PDraw Draw;
  251.  
  252. void SetDraw(int i)
  253. {
  254.     char ach[128];
  255.  
  256.     if (aDraw[i].Draw == NULL)
  257.         return;
  258.  
  259.     if (!aDraw[i].Init())
  260.         return;
  261.  
  262.     iDraw = i;
  263.     Draw = aDraw[i].Draw;
  264.     wsprintf(ach, "%s - %s - %dx%dx%d", (LPSTR)szAppName, (LPSTR)aDraw[i].szName, bm.bmWidth, bm.bmHeight, (int)biRgb.bi.biBitCount);
  265.     SetWindowText(hwndApp, ach);
  266. }
  267.  
  268. /*----------------------------------------------------------------------------*\
  269. |                                                                              |
  270. |   f u n c t i o n   d e f i n i t i o n s                                    |
  271. |                                                                              |
  272. \*----------------------------------------------------------------------------*/
  273.  
  274. LONG FAR PASCAL _export AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
  275. int  ErrMsg (LPSTR sz,...);
  276. LONG AppCommand (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
  277.  
  278. void AppExit(void);
  279. BOOL AppIdle(void);
  280. void AppOpenFile(HWND hwnd, LPSTR szFileName);
  281. void AppOpen(HWND hwnd, PDIB lpbi);
  282.  
  283. HPALETTE CreateColorPalette(int nr,int ng, int nb);
  284.  
  285. /*----------------------------------------------------------------------------*\
  286. |   AppAbout( hDlg, uiMessage, wParam, lParam )                                |
  287. |                                                                              |
  288. |   Description:                                                               |
  289. |       This function handles messages belonging to the "About" dialog box.    |
  290. |       The only message that it looks for is WM_COMMAND, indicating the use   |
  291. |       has pressed the "OK" button.  When this happens, it takes down         |
  292. |       the dialog box.                                                        |
  293. |                                                                              |
  294. |   Arguments:                                                                 |
  295. |       hDlg            window handle of about dialog window                   |
  296. |       uiMessage       message number                                         |
  297. |       wParam          message-dependent                                      |
  298. |       lParam          message-dependent                                      |
  299. |                                                                              |
  300. |   Returns:                                                                   |
  301. |       TRUE if message has been processed, else FALSE                         |
  302. |                                                                              |
  303. \*----------------------------------------------------------------------------*/
  304. BOOL FAR PASCAL _export AppAbout(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  305. {
  306.     switch (msg)
  307.     {
  308.         case WM_COMMAND:
  309.         if (LOWORD(wParam) == IDOK)
  310.             {
  311.                 EndDialog(hwnd,TRUE);
  312.             }
  313.             break;
  314.  
  315.         case WM_INITDIALOG:
  316.             return TRUE;
  317.     }
  318.     return FALSE;
  319. }
  320.  
  321. /*----------------------------------------------------------------------------*\
  322. |   AppInit( hInst, hPrev)                                                     |
  323. |                                                                              |
  324. |   Description:                                                               |
  325. |       This is called when the application is first loaded into               |
  326. |       memory.  It performs all initialization that doesn't need to be done   |
  327. |       once per instance.                                                     |
  328. |                                                                              |
  329. |   Arguments:                                                                 |
  330. |       hInstance       instance handle of current instance                    |
  331. |       hPrev           instance handle of previous instance                   |
  332. |                                                                              |
  333. |   Returns:                                                                   |
  334. |       TRUE if successful, FALSE if not                                       |
  335. |                                                                              |
  336. \*----------------------------------------------------------------------------*/
  337. BOOL AppInit(HINSTANCE hInst,HINSTANCE hPrev,int sw,LPSTR szCmdLine)
  338. {
  339.     WNDCLASS cls;
  340.     int      dx,dy;
  341.     int      i;
  342.  
  343.     /* Save instance handle for DialogBoxs */
  344.     hInstApp = hInst;
  345.  
  346.     hAccelApp = LoadAccelerators(hInst, "AppAccel");
  347.  
  348.     if (!hPrev)
  349.     {
  350.         /*
  351.          *  Register a class for the main application window
  352.          */
  353.         cls.hCursor        = LoadCursor(NULL,IDC_ARROW);
  354.         cls.hIcon          = LoadIcon(hInst,"AppIcon");
  355.         cls.lpszMenuName   = "AppMenu";
  356.         cls.lpszClassName  = szAppName;
  357.         cls.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  358.         cls.hInstance      = hInst;
  359.         cls.style          = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
  360.         cls.lpfnWndProc    = (WNDPROC)AppWndProc;
  361.         cls.cbWndExtra     = 0;
  362.         cls.cbClsExtra     = 0;
  363.  
  364.         if (!RegisterClass(&cls))
  365.             return FALSE;
  366.     }
  367.  
  368.     dx = GetSystemMetrics (SM_CXSCREEN) * 3 / 4;
  369.     dy = GetSystemMetrics (SM_CYSCREEN) * 3 / 4;
  370.  
  371.     hwndApp = CreateWindow (szAppName,    // Class name
  372.                             szAppName,              // Caption
  373.                             WS_OVERLAPPEDWINDOW,    // Style bits
  374.                             CW_USEDEFAULT, 0,       // Position
  375.                 dx,dy,            // Size
  376.                             (HWND)NULL,             // Parent window (no parent)
  377.                             (HMENU)NULL,            // use class menu
  378.                             hInst,                  // handle to window instance
  379.                             (LPSTR)NULL             // no params to pass on
  380.                            );
  381.     ShowWindow(hwndApp,sw);
  382.  
  383.     //
  384.     // init every thing.
  385.     //
  386.     for (i=0; i<NUM_DRAW; i++)
  387.     {
  388.         if (aDraw[i].Init == NULL)
  389.             aDraw[i].Init = InitYES;
  390.     }
  391.  
  392.     for (i=0; i<NUM_DRAW; i++)
  393.     {
  394.         if (!aDraw[i].Init())
  395.             aDraw[i].Draw = NULL;
  396.     }
  397.                
  398.     if (*szCmdLine)
  399.         AppOpenFile(hwndApp, szCmdLine);
  400.     else
  401.         AppOpenFile(hwndApp, "Herman");
  402.  
  403.     RandomSeed = (UINT)timeGetTime();
  404.     srand(RandomSeed);
  405.  
  406.     hpalBack = CreateColorPalette(6,6,6);
  407.  
  408.     //
  409.     // build the draw menu.
  410.     //
  411.     HMENU hmenu = GetSubMenu(GetMenu(hwndApp), 1);
  412.     DeleteMenu(hmenu, MENU_DRAW, MF_BYCOMMAND);
  413.  
  414.     for (i=0; i<NUM_DRAW; i++)
  415.     {
  416.         if (aDraw[i].szName == NULL)
  417.             AppendMenu(hmenu, MF_SEPARATOR, -1, NULL);
  418.         else
  419.             AppendMenu(hmenu, 0, MENU_DRAW+i, aDraw[i].szName);
  420.     }
  421.  
  422.     hmenu = GetSubMenu(GetMenu(hwndApp), 2);
  423.     AppendMenu(hmenu, MF_SEPARATOR, -1, NULL);
  424.     AppendMenu(hmenu, 0, MENU_IDENTPAL, "Identity Palette");
  425.     AppendMenu(hmenu, 0, MENU_BACKPAL,  "Background Pal");
  426.     AppendMenu(hmenu, 0, MENU_CLIP,     "Clipping");
  427.     AppendMenu(hmenu, 0, MENU_STRETCH,  "Stretch");
  428.     AppendMenu(hmenu, 0, MENU_MIRROR,   "Mirror");
  429.     AppendMenu(hmenu, 0, MENU_COPY,     "Copy");
  430.  
  431.     // pick a default.
  432.     SetDraw(0);
  433.  
  434.     return TRUE;
  435. }
  436.  
  437.  
  438. /*----------------------------------------------------------------------------*\
  439. |   AppExit()                                       |
  440. |                                                                              |
  441. |   Description:                                                               |
  442. |    app is just about to exit, cleanup                       |
  443. |                                                                              |
  444. \*----------------------------------------------------------------------------*/
  445. void AppExit()
  446. {
  447.     DeleteObject(hrgnClip);
  448.     DeleteObject(hpalBack);
  449.     AppOpen(hwndApp, NULL);
  450. }
  451.  
  452. /*----------------------------------------------------------------------------*\
  453. \*----------------------------------------------------------------------------*/
  454.  
  455. #define RandRGB() RGB(rand() % 256, rand() % 256, rand() % 256)
  456. #define RandPT(pt, rc) ((pt).x = rc.left + (rand() % (rc.right-rc.left))), ((pt).y = rc.top + (rand() % (rc.bottom-rc.top)))
  457.  
  458. RECT    rcRand;
  459. RECT    rcApp;
  460.  
  461. void InitDC(HDC hdc)
  462. {
  463.     if (gfBackPal)
  464.     {
  465.         SelectPalette(hdc, hpalBack, FALSE);
  466.         RealizePalette(hdc);
  467.  
  468.         if (hpalApp)
  469.             SelectPalette(hdc, hpalApp, TRUE);
  470.  
  471.         RealizePalette(hdc);
  472.     }
  473.     else
  474.     {
  475.         if (hpalApp)
  476.             SelectPalette(hdc, hpalApp, FALSE);
  477.  
  478.         RealizePalette(hdc);
  479.     }
  480.  
  481.     if (gfClipping && hrgnClip)
  482.         SelectClipRgn(hdc, hrgnClip);
  483.  
  484.     SetStretchBltMode(hdc, COLORONCOLOR);
  485.     GetPixel(hdc, 0, 0);        //!!! hack for DVA
  486. }
  487.  
  488. void DrawRandom(HDC hdc)
  489. {
  490.     BOOL f;
  491.     POINT pt;
  492.     POINT ptW;
  493.     int dx,dy;
  494.  
  495.     if (f = (hdc == NULL))
  496.     {
  497.         hdc = GetDC(hwndApp);
  498.         InitDC(hdc);
  499.     }
  500.  
  501.     if (gfStretch)
  502.     {
  503.         RandPT(pt, rcApp);
  504.         RandPT(ptW,rcApp);
  505.  
  506.         dx = ptW.x - pt.x;
  507.         dy = ptW.y - pt.y;
  508.  
  509.         if (!gfMirror)
  510.         {
  511.             if (dx < 0)
  512.                 pt.x = ptW.x, dx = -dx;
  513.  
  514.             if (dy < 0)
  515.                 pt.y = ptW.y, dy = -dy;
  516.         }
  517.     }
  518.     else
  519.     {
  520.         RandPT(pt, rcRand);
  521.  
  522.         dx = bm.bmWidth;
  523.         dy = bm.bmHeight;
  524.     }
  525.  
  526.     Draw(hdc, pt.x, pt.y, dx, dy);
  527.  
  528.     if (f)
  529.         ReleaseDC(hwndApp, hdc);
  530. }
  531.  
  532. void CopyText(LPSTR pch)
  533. {
  534.         HANDLE h = GlobalAlloc(GHND, lstrlen(pch)+1);
  535.     lstrcpy((LPSTR)GlobalLock(h), pch);
  536.     OpenClipboard(hwndApp);
  537.     EmptyClipboard();
  538.     SetClipboardData(CF_TEXT, h);
  539.     CloseClipboard();
  540. }
  541.  
  542. /*----------------------------------------------------------------------------*\
  543. |   TimeIt()                                                                 |
  544. \*----------------------------------------------------------------------------*/
  545.  
  546. #define N 100
  547.  
  548. #define FPS(time,n) \
  549.             time ? (1000l * n / time) : 0, \
  550.             time ? (1000000l * n / time) % 1000: 0
  551.  
  552. #define XPS(x) (x) / 1000, (x) % 1000
  553.  
  554. char achMsg[4096];
  555. char ach[256];
  556.  
  557. void TimeIt(int time_this)
  558. {
  559.     HDC hdc;
  560.     LONG time;
  561.     LONG time0;
  562.     int i,n;
  563.     char *pch;
  564.     HCURSOR hcur;
  565.     int iDrawSave;
  566.     LONG minTime;
  567.     int Count = N;
  568.  
  569.     if (bm.bmWidth <= 100)
  570.         Count = 500;
  571.  
  572.     InvalidateRect(hwndApp, NULL, TRUE);
  573.     UpdateWindow(hwndApp);
  574.  
  575.     hcur = SetCursor(NULL);
  576.  
  577.     iDrawSave = iDraw;
  578.  
  579.     hdc = GetDC(hwndApp);
  580.  
  581.     Draw = DrawNull;
  582.     time0 = timeGetTime();
  583.     for (i=0; i<Count; i++) DrawRandom(hdc);
  584.     time0 = timeGetTime() - time0;
  585.  
  586.     for (n=0; n<NUM_DRAW; n++)
  587.     {
  588.         if (aDraw[n].Draw == NULL || !aDraw[n].Init())
  589.             continue;
  590.  
  591.         if (time_this != -1 && time_this != n)
  592.             continue;
  593.  
  594.         SetDraw(n);
  595.         InitDC(hdc);
  596.         DrawRandom(hdc);
  597.  
  598.         srand(RandomSeed);
  599.  
  600.         time = timeGetTime();
  601.  
  602.         for (i=0; i<Count; i++)
  603.             DrawRandom(hdc);
  604.  
  605.         time = timeGetTime() - time - time0;
  606.  
  607.         aDraw[n].time = time;
  608.         aDraw[n].count = Count;
  609.     }
  610.  
  611.     SetCursor(hcur);
  612.     ReleaseDC(hwndApp, hdc);
  613.  
  614.     SetDraw(iDrawSave);
  615.  
  616.     //
  617.     //  now make a list box, and text to put into the clipboard.
  618.     //
  619.     {
  620.     HWND hwndLB;
  621.     static int tabs[] = {100,120,140};
  622.     RECT rc;
  623.  
  624.     GetWindowRect(hwndApp, &rc);
  625.  
  626.     wsprintf(ach, "%s - Results", (LPSTR)szAppName);
  627.  
  628.     hwndLB = CreateWindow("ListBox", ach,
  629.             LBS_NOINTEGRALHEIGHT|LBS_USETABSTOPS|
  630.             WS_POPUP | WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME,
  631.             rc.left + (rc.right - rc.left)*1/3 /2,
  632.             rc.top  + (rc.bottom - rc.top)*1/3 /2,
  633.             (rc.right - rc.left)*2/3,
  634.             (rc.bottom - rc.top)*2/3,
  635.             (HWND)hwndApp, (HMENU)NULL, hInstApp, NULL);
  636.  
  637.     SetWindowFont(hwndLB, GetStockObject(ANSI_VAR_FONT), TRUE);
  638.     ListBox_SetTabStops(hwndLB, sizeof(tabs)/sizeof(tabs[0]), tabs);
  639.  
  640.     pch = achMsg;
  641.  
  642.     minTime = 0x7FFFFFF;    //maxint?
  643.  
  644.     for (n=0; n<NUM_DRAW; n++)
  645.     {
  646.         if (aDraw[n].Draw == NULL || aDraw[n].time == 0)
  647.             continue;
  648.  
  649.         minTime = min(minTime,aDraw[n].time);
  650.     }
  651.  
  652. ////wsprintf(ach, "%s\t%3ld.%03ld", (LPSTR)"Overhead", time0/1000, time0%1000);
  653. ////ListBox_AddString(hwndLB, ach);
  654.  
  655.     for (n=0; n<NUM_DRAW; n++)
  656.     {
  657.         if (aDraw[n].Draw == NULL || aDraw[n].time == 0)
  658.             continue;
  659.  
  660.         wsprintf(ach, "%s\t%3ld.%03ld\t(%ld%%)", (LPSTR)aDraw[n].szName, FPS(aDraw[n].time,Count), minTime*100/aDraw[n].time);
  661.         ListBox_AddString(hwndLB, ach);
  662.  
  663.         lstrcpy(pch, ach);
  664.         lstrcat(pch, "\r\n");
  665.         pch += lstrlen(pch);
  666.     }
  667.  
  668.     CopyText(achMsg);
  669.     }
  670.  
  671. ////ErrMsg(achMsg);
  672. }
  673.  
  674. void BigTime()
  675. {
  676.     HDC hdc;
  677.     LONG time;
  678.     int i,n,z;
  679.     char *pch;
  680.     HCURSOR hcur;
  681.     int iDrawSave;
  682.     int Count = N;
  683.  
  684.     InvalidateRect(hwndApp, NULL, TRUE);
  685.     UpdateWindow(hwndApp);
  686.  
  687.     hcur = SetCursor(NULL);
  688.  
  689.     iDrawSave = iDraw;
  690.  
  691.     hdc = GetDC(hwndApp);
  692.  
  693.     GetAsyncKeyState(VK_ESCAPE);
  694.  
  695.     for (z=1; z<=10; z++)
  696.     {
  697.         SendMessage(hwndApp, WM_COMMAND, MENU_SIZE+32*z, 0);
  698.  
  699.         if (bm.bmWidth <= 128)
  700.             Count = 500;
  701.         else
  702.             Count = 100;
  703.  
  704.         for (n=0; n<NUM_DRAW; n++)
  705.         {
  706.             if (aDraw[n].Draw == NULL || !aDraw[n].Init())
  707.                 continue;
  708. #if 0
  709.             if (aDraw[n].Draw == DoSetBitmapBitsBitBlt ||
  710.                 aDraw[n].Draw == DoSetDIBitsPalBitBlt ||
  711.                 aDraw[n].Draw == DoSetDIBitsRgbBitBlt)
  712.             {
  713.                 aDraw[n].time = 0;
  714.                 continue;
  715.             }
  716. #endif
  717.  
  718.             SetDraw(n);
  719.             InitDC(hdc);
  720.             DrawRandom(hdc);
  721.  
  722.             srand(RandomSeed);
  723.  
  724.             if (GetAsyncKeyState(VK_ESCAPE))
  725.                 goto bail;
  726.  
  727.             time = timeGetTime();
  728.  
  729.             for (i=0; i<Count; i++)
  730.                 DrawRandom(hdc);
  731.  
  732.             time = timeGetTime() - time;
  733.  
  734.             aDraw[n].time = time;
  735.             aDraw[n].pps[z] = (DWORD)((double)bm.bmWidth * bm.bmHeight * Count * 1000 / time);
  736.         }
  737.     }
  738.  
  739. bail:
  740.     SetCursor(hcur);
  741.     ReleaseDC(hwndApp, hdc);
  742.  
  743.     SetDraw(iDrawSave);
  744.  
  745.     //
  746.     //  now make a list box, and text to put into the clipboard.
  747.     //
  748.     {
  749.     HWND hwndLB;
  750.     static int tabs[] = {100,120,140,160,180,200,220,240,260,280,300,320,340,360,380,400};
  751.     RECT rc;
  752.  
  753.     GetWindowRect(hwndApp, &rc);
  754.  
  755.     wsprintf(ach, "%s - Results", (LPSTR)szAppName);
  756.  
  757.     hwndLB = CreateWindow("ListBox", ach,
  758.             LBS_NOINTEGRALHEIGHT|LBS_USETABSTOPS|
  759.             WS_POPUP | WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME,
  760.             rc.left + (rc.right - rc.left)*1/3 /2,
  761.             rc.top  + (rc.bottom - rc.top)*1/3 /2,
  762.             (rc.right - rc.left)*2/3,
  763.             (rc.bottom - rc.top)*2/3,
  764.             (HWND)hwndApp, (HMENU)NULL, hInstApp, NULL);
  765.  
  766.     SetWindowFont(hwndLB, GetStockObject(ANSI_VAR_FONT), TRUE);
  767.     ListBox_SetTabStops(hwndLB, sizeof(tabs)/sizeof(tabs[0]), tabs);
  768.     pch = achMsg;
  769.  
  770.     wsprintf(ach, "%s\t  %dx%d\t  %dx%d\t  %dx%d\t  %dx%d\t  %dx%d\t  %dx%d\t  %dx%d\t  %dx%d\t  %dx%d\t  %dx%d",
  771.         (LPSTR)"Pixels/mSec",
  772.         32*1,32*1,
  773.         32*2,32*2,
  774.         32*3,32*3,
  775.         32*4,32*4,
  776.         32*5,32*5,
  777.         32*6,32*6,
  778.         32*7,32*7,
  779.         32*8,32*8,
  780.         32*9,32*9,
  781.         32*10,32*10);
  782.     ListBox_AddString(hwndLB, ach);
  783.  
  784.     lstrcpy(pch, ach);
  785.     lstrcat(pch, "\r\n");
  786.     pch += lstrlen(pch);
  787.  
  788.     for (n=0; n<NUM_DRAW; n++)
  789.     {
  790.         if (aDraw[n].Draw == NULL || aDraw[n].time == 0)
  791.             continue;
  792.  
  793.         wsprintf(ach, "%s"
  794.             "\t%3ld.%03ld"
  795.             "\t%3ld.%03ld"
  796.             "\t%3ld.%03ld"
  797.             "\t%3ld.%03ld"
  798.             "\t%3ld.%03ld"
  799.             "\t%3ld.%03ld"
  800.             "\t%3ld.%03ld"
  801.             "\t%3ld.%03ld"
  802.             "\t%3ld.%03ld"
  803.             "\t%3ld.%03ld",
  804.             (LPSTR)aDraw[n].szName,
  805.             XPS(aDraw[n].pps[1]),
  806.             XPS(aDraw[n].pps[2]),
  807.             XPS(aDraw[n].pps[3]),
  808.             XPS(aDraw[n].pps[4]),
  809.             XPS(aDraw[n].pps[5]),
  810.             XPS(aDraw[n].pps[6]),
  811.             XPS(aDraw[n].pps[7]),
  812.             XPS(aDraw[n].pps[8]),
  813.             XPS(aDraw[n].pps[9]),
  814.             XPS(aDraw[n].pps[10]));
  815.         ListBox_AddString(hwndLB, ach);
  816.  
  817.         lstrcpy(pch, ach);
  818.         lstrcat(pch, "\r\n");
  819.         pch += lstrlen(pch);
  820.     }
  821.  
  822.     CopyText(achMsg);
  823.     }
  824. }
  825.  
  826. /*----------------------------------------------------------------------------*\
  827. |   WinMain( hInst, hPrev, lpszCmdLine, cmdShow )                              |
  828. |                                                                              |
  829. |   Description:                                                               |
  830. |       The main procedure for the App.  After initializing, it just goes      |
  831. |       into a message-processing loop until it gets a WM_QUIT message         |
  832. |       (meaning the app was closed).                                          |
  833. |                                                                              |
  834. |   Arguments:                                                                 |
  835. |       hInst           instance handle of this instance of the app            |
  836. |       hPrev           instance handle of previous instance, NULL if first    |
  837. |       szCmdLine       ->null-terminated command line                         |
  838. |       cmdShow         specifies how the window is initially displayed        |
  839. |                                                                              |
  840. |   Returns:                                                                   |
  841. |       The exit code as specified in the WM_QUIT message.                     |
  842. |                                                                              |
  843. \*----------------------------------------------------------------------------*/
  844. int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
  845. {
  846.     MSG     msg;
  847.  
  848.     /* Call initialization procedure */
  849.     if (!AppInit(hInst,hPrev,sw,szCmdLine))
  850.     return FALSE;
  851.  
  852.     /*
  853.      * Polling messages from event queue
  854.      */
  855.     for (;;)
  856.     {
  857.         if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
  858.         {
  859.             if (msg.message == WM_QUIT)
  860.                 break;
  861.  
  862.         if (hAccelApp && TranslateAccelerator(hwndApp, hAccelApp, &msg))
  863.         continue;
  864.  
  865.             TranslateMessage(&msg);
  866.             DispatchMessage(&msg);
  867.         }
  868.         else
  869.     {
  870.         if (AppIdle())
  871.                 WaitMessage();
  872.         }
  873.     }
  874.  
  875.     AppExit();
  876.     return msg.wParam;
  877. }
  878.  
  879. /*----------------------------------------------------------------------------*\
  880. |   AppIdle()                                       |
  881. |                                                                              |
  882. |   Description:                                                               |
  883. |    place to do idle time stuff.                           |
  884. |                                                                              |
  885. |   Returns:                                       |
  886. |    RETURN TRUE IF YOU HAVE NOTHING TO DO OTHERWISE YOUR APP WILL BE A     |
  887. |    CPU PIG!                                   |
  888. \*----------------------------------------------------------------------------*/
  889. BOOL AppIdle()
  890. {
  891.     if (fAppActive)
  892.     {
  893.     //
  894.     // we are the foreground app.
  895.         //
  896.         if (lpbiApp)
  897.         {
  898.             DrawRandom(NULL);
  899.             return FALSE;
  900.         }
  901.  
  902.     return TRUE;        // nothing to do.
  903.     }
  904.     else
  905.     {
  906.     //
  907.     // we are a background app.
  908.     //
  909.     return TRUE;        // nothing to do.
  910.     }
  911. }
  912.  
  913. /*----------------------------------------------------------------------------*\
  914. |   AppOpenFile()                                   |
  915. |                                                                              |
  916. |   Description:                                                               |
  917. |    open a file stupid                               |
  918. |                                                                              |
  919. \*----------------------------------------------------------------------------*/
  920. void AppOpenFile(HWND hwnd, LPSTR szFileName)
  921. {
  922.     PDIB lpbi = DibOpenFile(szFileName);
  923.  
  924.     if (lpbi == NULL)
  925.     {
  926.         ErrMsg("Cant open %s", szFileName);
  927.         return;
  928.     }
  929.  
  930.     AppOpen(hwndApp, lpbi);
  931. }
  932.  
  933. void AppOpen(HWND hwnd, PDIB lpbi)
  934. {
  935.     HDC hdc;
  936.     LPVOID lpBits;
  937.  
  938.     if (hdcApp)  SelectObject(hdcApp, hbmMono);
  939.     if (hdcApp)  SelectPalette(hdcApp, (HPALETTE)GetStockObject(DEFAULT_PALETTE), FALSE);
  940.     if (hdcDS)   SelectObject(hdcDS, hbmMono);
  941.  
  942.     if (hpalApp) DeleteObject(hpalApp);
  943.     if (hdcApp)  DeleteObject(hdcApp);
  944.     if (hbmApp)  DeleteObject(hbmApp);
  945.     if (hdcDS)   DeleteObject(hdcDS);
  946.     if (hbmDS)   DeleteObject(hbmDS);
  947.     if (lpbiApp) DibFree(lpbiApp);
  948.  
  949.     hpalApp  = NULL;
  950.     lpbiApp  = NULL;
  951.     hbmApp   = NULL;
  952.     hdcApp   = NULL;
  953.  
  954.     if (lpbi == NULL)
  955.         return;
  956.  
  957.     lpbiApp = lpbi;
  958.  
  959.     if (!gfIdentPal)
  960.     {
  961.         //
  962.         // make sure it is not a ident palette.
  963.         //
  964.         DibColors(lpbiApp)[0].rgbRed++;
  965.     }
  966.  
  967.     //
  968.     // get the palette
  969.     //
  970.     hpalApp = DibCreatePalette(lpbiApp);
  971.  
  972.     //
  973.     //  make this a identity palette for fast drawing.
  974.     //
  975.     if (lpbiApp->biBitCount == 8 && gfIdentPal && hpalApp)
  976.     {
  977.         MakeIdentityPalette(hpalApp);
  978.         DibMapToPalette(lpbiApp, hpalApp);
  979.     }
  980.  
  981.     //
  982.     // convert to a bitmap
  983.     //
  984.     hbmApp = BitmapFromDib(lpbiApp, hpalApp, DIB_RGB_COLORS);
  985.  
  986.     //
  987.     // bitmap stuff.
  988.     //
  989.     GetObject(hbmApp, sizeof(bm), (LPVOID)&bm);
  990.     SizeImage = (DWORD)(UINT)bm.bmHeight * (DWORD)(UINT)bm.bmWidthBytes;
  991.     lpBitmapBits = (LPBYTE)GlobalAllocPtr(GHND, SizeImage);
  992.     BitmapTranslate = (LPBYTE)GlobalAllocPtr(GHND, 256);
  993.  
  994.     OffsetScan0 = SizeImage - bm.bmWidthBytes;
  995.     GetBitmapBits(hbmApp, SizeImage, lpBitmapBits);
  996.  
  997.     lpDibBits = DibPtr(lpbiApp);
  998.  
  999.     //
  1000.     // we will use DIB_PAL_COLORS to draw DIBs
  1001.     //
  1002.     hmemcpy(&biRgb, lpbiApp, sizeof(biRgb));        //save RGB colors
  1003.     hmemcpy(&biPal, lpbiApp, sizeof(biRgb));        //save RGB colors
  1004.     DibSetUsage((PDIB)&biPal, hpalApp, DIB_PAL_COLORS);
  1005.  
  1006.     //
  1007.     // make memory DCs for easy access.
  1008.     //
  1009.     hdc = GetDC(NULL);
  1010.  
  1011.     ScreenDepth = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
  1012.  
  1013.     //
  1014.     // make a DIBSECTION
  1015.     //
  1016.     if (XCreateDIBSection != NULL)
  1017.     {
  1018.         HBITMAP hbm;
  1019.  
  1020.         if (1)
  1021.             hbmDS = CreateDIBSection(hdc, (LPBITMAPINFO)&biRgb,  DIB_RGB_COLORS, &lpBits, NULL, 0);
  1022.         else
  1023.             hbmDS = CreateDIBSection(hdc, (LPBITMAPINFO)&biPal, DIB_PAL_COLORS, &lpBits, NULL, 0);
  1024.  
  1025.         if (hbmDS == NULL)
  1026.         {
  1027.             ErrMsg("Cant create DIBSection");
  1028.             goto nods;
  1029.         }
  1030.  
  1031.         GetObject(hbmDS, sizeof(ds), (LPVOID)&ds);
  1032.  
  1033.         hdcDS = CreateCompatibleDC(hdc);
  1034.  
  1035.  
  1036. #if 0
  1037.         hbm = (HBITMAP)SelectObject(hdcDS, hbmDS);
  1038.         PatBlt(hdcDS, 0, 0, bm.bmWidth, bm.bmHeight, BLACKNESS);
  1039.         SelectObject(hdcDS, hbm);
  1040.  
  1041. ////////hbm = (HBITMAP)SelectObject(hdcDS, hbmDS);
  1042.         // copy the bits.
  1043.         SetDIBits(hdc, hbmDS, 0, bm.bmHeight,
  1044.             lpDibBits, (LPBITMAPINFO)&biRgb, DIB_RGB_COLORS);
  1045.  
  1046.         //  get back the bits to make sure it works
  1047.         GetDIBits(hdc, hbmDS, 0, bm.bmHeight,
  1048.             lpDibBits, (LPBITMAPINFO)&biRgb, DIB_RGB_COLORS);
  1049. ////////SelectObject(hdcDS, hbm);
  1050.  
  1051.         hbm = (HBITMAP)SelectObject(hdcDS, hbmDS);
  1052.         PatBlt(hdcDS, 0, 0, bm.bmWidth, bm.bmHeight, BLACKNESS);
  1053.         SelectObject(hdcDS, hbm);
  1054. #endif
  1055.  
  1056.         SetDIBits(hdc, hbmDS, 0, bm.bmHeight,
  1057.             lpDibBits, (LPBITMAPINFO)&biRgb, DIB_RGB_COLORS);
  1058.  
  1059.         hbm = (HBITMAP)SelectObject(hdcDS, hbmDS);
  1060. nods:
  1061.         ;
  1062.     }
  1063.  
  1064.     for (int i=0; i<256; i++)
  1065.         BitmapTranslate[i] = i;
  1066.  
  1067.     for (i=0; i<NUM_DRAW; i++)
  1068.         aDraw[i].time = 0;
  1069.  
  1070.     hdcApp = CreateCompatibleDC(hdc);
  1071.     ReleaseDC(NULL, hdc);
  1072.  
  1073.     hbmMono = (HBITMAP)SelectObject(hdcApp, hbmApp);
  1074.  
  1075.     // do this so StretchBlt etc will work
  1076.     if (hpalApp)
  1077.         SelectPalette(hdcApp, hpalApp, FALSE);
  1078.     RealizePalette(hdcApp);
  1079.  
  1080.     SendMessage(hwndApp, WM_SIZE, 0, 0);
  1081. }
  1082.  
  1083. /*----------------------------------------------------------------------------*\
  1084. |   AppPaint(hwnd, hdc)                                                        |
  1085. |                                                                              |
  1086. |   Description:                                                               |
  1087. |       The paint function.  Right now this does nothing.                      |
  1088. |                                                                              |
  1089. |   Arguments:                                                                 |
  1090. |       hwnd             window painting into                                  |
  1091. |       hdc              display context to paint to                           |
  1092. |                                                                              |
  1093. |   Returns:                                                                   |
  1094. |       nothing                                                                |
  1095. |                                                                              |
  1096. \*----------------------------------------------------------------------------*/
  1097. AppPaint (HWND hwnd, HDC hdc)
  1098. {
  1099.     return TRUE;
  1100. }
  1101.  
  1102. /*----------------------------------------------------------------------------*\
  1103. |   AppWndProc( hwnd, uiMessage, wParam, lParam )                              |
  1104. |                                                                              |
  1105. |   Description:                                                               |
  1106. |       The window proc for the app's main (tiled) window.  This processes all |
  1107. |       of the parent window's messages.                                       |
  1108. |                                                                              |
  1109. \*----------------------------------------------------------------------------*/
  1110. LONG FAR PASCAL _export AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  1111. {
  1112.     PAINTSTRUCT ps;
  1113.     HDC hdc;
  1114.     BOOL f;
  1115.     int i;
  1116.  
  1117.     switch (msg)
  1118.     {
  1119.         case WM_CREATE:
  1120.         break;
  1121.  
  1122. ////////case WM_ACTIVATEAPP:
  1123.         case WM_ACTIVATE:
  1124.         fAppActive = (BOOL)wParam;
  1125.         break;
  1126.  
  1127.         case WM_TIMER:
  1128.             break;
  1129.  
  1130.         case WM_ERASEBKGND:
  1131.             break;
  1132.  
  1133.         case WM_INITMENU:
  1134.             for (i=0; i<NUM_DRAW; i++)
  1135.             {
  1136.                 if (aDraw[i].Draw && aDraw[i].Init())
  1137.                     EnableMenuItem((HMENU)wParam, MENU_DRAW + i, MF_ENABLED);
  1138.                 else
  1139.                     EnableMenuItem((HMENU)wParam, MENU_DRAW + i, MF_GRAYED);
  1140.  
  1141.                 CheckMenuItem((HMENU)wParam, MENU_DRAW + i, iDraw == i ? MF_CHECKED : MF_UNCHECKED);
  1142.             }
  1143.  
  1144.             CheckMenuItem((HMENU)wParam, MENU_IDENTPAL, gfIdentPal ? MF_CHECKED : MF_UNCHECKED);
  1145.             CheckMenuItem((HMENU)wParam, MENU_BACKPAL, gfBackPal ? MF_CHECKED : MF_UNCHECKED);
  1146.             CheckMenuItem((HMENU)wParam, MENU_CLIP, gfClipping ? MF_CHECKED : MF_UNCHECKED);
  1147.             CheckMenuItem((HMENU)wParam, MENU_MIRROR, gfMirror ? MF_CHECKED : MF_UNCHECKED);
  1148.             CheckMenuItem((HMENU)wParam, MENU_STRETCH, gfStretch ? MF_CHECKED : MF_UNCHECKED);
  1149.  
  1150.             CheckMenuItem((HMENU)wParam, MENU_SIZE+16, TestSize == 16  ? MF_CHECKED : MF_UNCHECKED);
  1151.             CheckMenuItem((HMENU)wParam, MENU_SIZE+32, TestSize == 32  ? MF_CHECKED : MF_UNCHECKED);
  1152.             CheckMenuItem((HMENU)wParam, MENU_SIZE+64, TestSize == 64  ? MF_CHECKED : MF_UNCHECKED);
  1153.             CheckMenuItem((HMENU)wParam, MENU_SIZE+100,TestSize == 100 ? MF_CHECKED : MF_UNCHECKED);
  1154.             CheckMenuItem((HMENU)wParam, MENU_SIZE+200,TestSize == 200 ? MF_CHECKED : MF_UNCHECKED);
  1155.             CheckMenuItem((HMENU)wParam, MENU_SIZE+300,TestSize == 300 ? MF_CHECKED : MF_UNCHECKED);
  1156.  
  1157.             CheckMenuItem((HMENU)wParam, MENU_SIGN+1, TestSign == 1 ? MF_CHECKED : MF_UNCHECKED);
  1158.             CheckMenuItem((HMENU)wParam, MENU_SIGN-1, TestSign ==-1 ? MF_CHECKED : MF_UNCHECKED);
  1159.  
  1160.             EnableMenuItem((HMENU)wParam, MENU_IDENTPAL, ScreenDepth == (int)biRgb.bi.biBitCount ? MF_ENABLED : MF_GRAYED);
  1161.         break;
  1162.  
  1163.         case WM_COMMAND:
  1164.             return AppCommand(hwnd,msg,wParam,lParam);
  1165.  
  1166.     case WM_DESTROY:
  1167.         hAccelApp = NULL;
  1168.             PostQuitMessage(0);
  1169.             break;
  1170.  
  1171.         case WM_SIZE:
  1172.             InvalidateRect(hwnd, NULL, TRUE);
  1173.  
  1174.             GetClientRect(hwnd, &rcApp);
  1175.             GetClientRect(hwnd, &rcRand);
  1176.  
  1177.             if (lpbiApp == NULL)
  1178.                 return 0L;
  1179.  
  1180.             if ((int)bm.bmWidth < rcRand.right)
  1181.                 rcRand.right  -= bm.bmWidth;
  1182.  
  1183.             if ((int)bm.bmHeight < rcRand.bottom)
  1184.                 rcRand.bottom -= bm.bmHeight;
  1185.  
  1186.             if (hrgnClip)
  1187.                 DeleteObject(hrgnClip);
  1188.  
  1189.             hrgnClip = CreateEllipticRgn(0,0,rcApp.right,rcApp.bottom);
  1190.             break;
  1191.  
  1192.         case WM_CLOSE:
  1193.         break;
  1194.  
  1195.         case WM_PALETTECHANGED:
  1196.         if ((HWND)wParam == hwnd)
  1197.         break;
  1198.  
  1199.         // fall through to WM_QUERYNEWPALETTE
  1200.  
  1201.     case WM_QUERYNEWPALETTE:
  1202.         hdc = GetDC(hwnd);
  1203.  
  1204.         if (hpalApp)
  1205.         SelectPalette(hdc, hpalApp, FALSE);
  1206.  
  1207.         f = RealizePalette(hdc);
  1208.         ReleaseDC(hwnd,hdc);
  1209.  
  1210.         if (f)
  1211.         InvalidateRect(hwnd,NULL,TRUE);
  1212.  
  1213.         return f;
  1214.  
  1215.         case WM_PAINT:
  1216.         hdc = BeginPaint(hwnd,&ps);
  1217.         AppPaint (hwnd,hdc);
  1218.             EndPaint(hwnd,&ps);
  1219.             return 0L;
  1220.     }
  1221.     return DefWindowProc(hwnd,msg,wParam,lParam);
  1222. }
  1223.  
  1224. /*----------------------------------------------------------------------------*\
  1225. |   AppCommand(hwnd, msg, wParam, lParam )                       |
  1226. |                                                                              |
  1227. |   Description:                                                               |
  1228. |    handles WM_COMMAND messages for the main window (hwndApp)           |
  1229. |       of the parent window's messages.                                       |
  1230. |                                                                              |
  1231. \*----------------------------------------------------------------------------*/
  1232. LONG AppCommand (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  1233. {
  1234.     char achFileName[128];
  1235.     OPENFILENAME ofn;
  1236.     int i;
  1237.  
  1238.     switch(LOWORD(wParam))
  1239.     {
  1240.         case MENU_ABOUT:
  1241.         DialogBox(hInstApp,"AppAbout",hwnd,AppAbout);
  1242.             break;
  1243.  
  1244.         case MENU_COPY:
  1245.             OpenClipboard(hwnd);
  1246.             EmptyClipboard();
  1247.             SetClipboardData(CF_DIB, HandleFromDib(DibCopy(lpbiApp)));
  1248.             CloseClipboard();
  1249.             break;
  1250.  
  1251.     case MENU_OPEN:
  1252.             achFileName[0] = 0;
  1253.  
  1254.             /* prompt user for file to open */
  1255.             ofn.lStructSize = sizeof(OPENFILENAME);
  1256.             ofn.hwndOwner = hwnd;
  1257.             ofn.hInstance = NULL;
  1258.         ofn.lpstrFilter = szAppFilter;
  1259.             ofn.lpstrCustomFilter = NULL;
  1260.             ofn.nMaxCustFilter = 0;
  1261.             ofn.nFilterIndex = 0;
  1262.             ofn.lpstrFile = achFileName;
  1263.         ofn.nMaxFile = sizeof(achFileName);
  1264.             ofn.lpstrFileTitle = NULL;
  1265.             ofn.nMaxFileTitle = 0;
  1266.             ofn.lpstrInitialDir = NULL;
  1267.         ofn.lpstrTitle = NULL;
  1268.         ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
  1269.             ofn.nFileOffset = 0;
  1270.             ofn.nFileExtension = 0;
  1271.             ofn.lpstrDefExt = NULL;
  1272.             ofn.lCustData = 0;
  1273.             ofn.lpfnHook = NULL;
  1274.             ofn.lpTemplateName = NULL;
  1275.  
  1276.             if (GetOpenFileName(&ofn))
  1277.             {
  1278.         AppOpenFile(hwnd,achFileName);
  1279.             }
  1280.  
  1281.             break;
  1282.  
  1283.         case MENU_EXIT:
  1284.             PostMessage(hwnd,WM_CLOSE,0,0L);
  1285.             break;
  1286.  
  1287.         case MENU_TIME:
  1288.             TimeIt(iDraw);
  1289.             break;
  1290.  
  1291.         case MENU_TIMEALL:
  1292.             TimeIt(-1);
  1293.             break;
  1294.  
  1295.         case MENU_TIMEXXX:
  1296.             BigTime();
  1297.             break;
  1298.  
  1299.         case MENU_BACKPAL:
  1300.             gfBackPal = !gfBackPal;
  1301.             PostMessage(hwnd, WM_SIZE, 0, 0);
  1302.             break;
  1303.  
  1304.         case MENU_IDENTPAL:
  1305.             gfIdentPal = !gfIdentPal;
  1306.             AppOpen(hwnd, DibCopy(lpbiApp));
  1307.             break;
  1308.  
  1309.         case MENU_CLIP:
  1310.             gfClipping = !gfClipping;
  1311.             PostMessage(hwnd, WM_SIZE, 0, 0);
  1312.             break;
  1313.  
  1314.         case MENU_MIRROR:
  1315.             gfMirror = !gfMirror;
  1316.             PostMessage(hwnd, WM_SIZE, 0, 0);
  1317.             break;
  1318.  
  1319.         case MENU_STRETCH:
  1320.             gfStretch = !gfStretch;
  1321.             PostMessage(hwnd, WM_SIZE, 0, 0);
  1322.             break;
  1323.  
  1324.         case MENU_SIGN+1:
  1325.         case MENU_SIGN-1:
  1326.             TestSign = (int)wParam - MENU_SIGN;
  1327.             PostMessage(hwnd, WM_COMMAND, MENU_TEST+(int)biRgb.bi.biBitCount, 0);
  1328.             break;
  1329.  
  1330.         case MENU_TEST+15:
  1331.             AppOpen(hwnd, MakeDib(16, TestSize, TestSize*TestSign, 0));
  1332.             break;
  1333.  
  1334.         case MENU_TEST+16:
  1335.             AppOpen(hwnd, MakeDib(16, TestSize, TestSize*TestSign, DIB_TYPE_565));
  1336.             break;
  1337.  
  1338.         case MENU_RLE+8:
  1339.             AppOpen(hwnd, MakeDib(8, TestSize, TestSize*TestSign, BI_RLE8));
  1340.             break;
  1341.  
  1342.         case MENU_RLE+4:
  1343.             AppOpen(hwnd, MakeDib(4, TestSize, TestSize*TestSign, BI_RLE4));
  1344.             break;
  1345.  
  1346.         case MENU_TEST+1:
  1347.         case MENU_TEST+4:
  1348.         case MENU_TEST+8:
  1349.         case MENU_TEST+24:
  1350.         case MENU_TEST+32:
  1351.             AppOpen(hwnd, MakeDib((int)wParam - MENU_TEST, TestSize, TestSize*TestSign, 0));
  1352.             break;
  1353.  
  1354.     default:
  1355.             i = (int)LOWORD(wParam) - MENU_SIZE;
  1356.  
  1357.             if (i >= 0 && i <= 512)
  1358.             {
  1359.                 TestSize = (int)wParam - MENU_SIZE;
  1360.                 SendMessage(hwnd, WM_COMMAND, MENU_TEST+(int)biRgb.bi.biBitCount, 0);
  1361.                 break;
  1362.             }
  1363.  
  1364.         i = (int)LOWORD(wParam) - MENU_DRAW;
  1365.         
  1366.             if (i >= 0 && i < NUM_DRAW && aDraw[i].Draw)
  1367.                 SetDraw(i);
  1368.             
  1369.             InvalidateRect(hwnd, NULL, TRUE);
  1370.             break;
  1371.     }
  1372.     return 0L;
  1373. }
  1374.  
  1375. /*----------------------------------------------------------------------------*\
  1376. |   ErrMsg - Opens a Message box with a error message in it.  The user can     |
  1377. |            select the OK button to continue                                  |
  1378. \*----------------------------------------------------------------------------*/
  1379. int ErrMsg (LPSTR sz,...)
  1380. {
  1381.     static char ach[4096];
  1382.  
  1383.     wvsprintf (ach,sz,(LPSTR)(&sz+1));   /* Format the string */
  1384.     MessageBox(hwndApp,ach,szAppName,MB_OK|MB_ICONEXCLAMATION|MB_TASKMODAL);
  1385.     return FALSE;
  1386. }
  1387.  
  1388. typedef void (FAR PASCAL CONVERTPROC)(
  1389.         LPVOID pd,              // --> dst.
  1390.         LONG   dd,              // offset to start at
  1391.         LONG   nd,              // dst_next_scan.
  1392.         LPVOID ps,              // --> source.
  1393.         LONG   ds,              // offset to start at
  1394.         LONG   ns,              // src_next_scan.
  1395.         LONG   dx,              // pixel count.
  1396.         LONG   dy,              // scan count.
  1397.         LPVOID pc);             // pixel convert table.
  1398.  
  1399. extern "C" CONVERTPROC copy_8_8, convert_8_8;
  1400.  
  1401. void DrawDRGB(HDC hdc, int x, int y, int dx, int dy)
  1402. {
  1403.     StretchDIBits(
  1404.         hdc,
  1405.         x,y,dx,dy,
  1406.         0,0,
  1407.         bm.bmWidth,
  1408.         bm.bmHeight,
  1409.         lpDibBits,
  1410.         (LPBITMAPINFO)&biRgb,
  1411.         DIB_RGB_COLORS,SRCCOPY);
  1412. }
  1413.  
  1414. void DrawDPAL(HDC hdc, int x, int y, int dx, int dy)
  1415. {
  1416.     StretchDIBits(
  1417.         hdc,
  1418.         x,y,dx,dy,
  1419.         0,0,
  1420.         bm.bmWidth,
  1421.         bm.bmHeight,
  1422.         lpDibBits,
  1423.         (LPBITMAPINFO)&biPal,
  1424.         DIB_PAL_COLORS,SRCCOPY);
  1425. }
  1426.  
  1427. #ifdef WIN32
  1428. void DrawDIDX(HDC hdc, int x, int y, int dx, int dy)
  1429. {
  1430.     StretchDIBits(
  1431.         hdc,
  1432.         x,y,dx,dy,
  1433.         0,0,
  1434.         bm.bmWidth,
  1435.         bm.bmHeight,
  1436.         lpDibBits,
  1437.         (LPBITMAPINFO)&biRgb,
  1438.         DIB_PAL_INDICES,SRCCOPY);
  1439. }
  1440. #endif
  1441.  
  1442. void DrawRGB(HDC hdc, int x, int y, int dx, int dy)
  1443. {
  1444.     SetDIBitsToDevice(hdc, x, y, dx, dy,
  1445.         0, 0, 0, bm.bmHeight, lpDibBits,
  1446.         (LPBITMAPINFO)&biRgb, DIB_RGB_COLORS);
  1447. }
  1448.  
  1449. void DrawPAL(HDC hdc, int x, int y, int dx, int dy)
  1450. {
  1451.     SetDIBitsToDevice(hdc, x, y, dx, dy,
  1452.         0, 0, 0, bm.bmHeight, lpDibBits,
  1453.         (LPBITMAPINFO)&biPal, DIB_PAL_COLORS);
  1454. }
  1455.  
  1456. #ifdef WIN32
  1457. void DrawIDX(HDC hdc, int x, int y, int dx, int dy)
  1458. {
  1459.     SetDIBitsToDevice(hdc, x, y, dx, dy,
  1460.         0, 0, 0, bm.bmHeight, lpDibBits,
  1461.         (LPBITMAPINFO)&biRgb, DIB_PAL_INDICES);
  1462. }
  1463. #endif
  1464.  
  1465. void DrawBLT(HDC hdc, int x, int y, int dx, int dy)
  1466. {
  1467.     //  Flush cached bitmaps
  1468.     SetPixelV(hdcApp, 0, 0, 0L);
  1469.     BitBlt(hdc, x, y, dx, dy, hdcApp, 0, 0, SRCCOPY);
  1470. }
  1471.  
  1472. void DrawSB(HDC hdc, int x, int y, int dx, int dy)
  1473. {
  1474.     //  Flush cached bitmaps
  1475.     SetPixelV(hdcApp, 0, 0, 0L);
  1476.     StretchBlt(hdc, x, y, dx, dy,
  1477.             hdcApp, 0, 0,
  1478.             bm.bmWidth, bm.bmHeight,
  1479.             SRCCOPY);
  1480. }
  1481.  
  1482. void DrawBLTDS(HDC hdc, int x, int y, int dx, int dy)
  1483. {
  1484.     BitBlt(hdc, x, y, dx, dy,hdcDS, 0, 0, SRCCOPY);
  1485. }
  1486.  
  1487. void DrawSBDS(HDC hdc, int x, int y, int dx, int dy)
  1488. {
  1489.     StretchBlt(hdc, x, y, dx, dy,
  1490.             hdcDS, 0, 0,bm.bmWidth, bm.bmHeight,SRCCOPY);
  1491. }
  1492.  
  1493. void DoSetBitmapBitsBitBlt(HDC hdc, int x, int y, int dx, int dy)
  1494. {
  1495.     SetBitmapBits(hbmApp, SizeImage, lpBitmapBits);
  1496.  
  1497.     StretchBlt(hdc, x, y, dx, dy,
  1498.         hdcApp, 0, 0,
  1499.         bm.bmWidth, bm.bmHeight,
  1500.         SRCCOPY);
  1501. }
  1502.  
  1503. void DoSetDIBitsPalBitBlt(HDC hdc, int x, int y, int dx, int dy)
  1504. {
  1505.     SetDIBits(hdc, hbmApp, 0, bm.bmHeight, lpDibBits,
  1506.             (LPBITMAPINFO)&biPal, DIB_PAL_COLORS);
  1507.  
  1508.     StretchBlt(hdc, x, y, dx, dy,
  1509.         hdcApp, 0, 0,
  1510.         bm.bmWidth, bm.bmHeight,
  1511.         SRCCOPY);
  1512. }
  1513.  
  1514. void DoSetDIBitsRgbBitBlt(HDC hdc, int x, int y, int dx, int dy)
  1515. {
  1516.     SetDIBits(hdc, hbmApp, 0, bm.bmHeight, lpDibBits,
  1517.             (LPBITMAPINFO)&biRgb, DIB_RGB_COLORS);
  1518.  
  1519.     StretchBlt(hdc, x, y, dx, dy,
  1520.         hdcApp, 0, 0,
  1521.         bm.bmWidth, bm.bmHeight,
  1522.         SRCCOPY);
  1523. }
  1524.  
  1525. void DoSetDIBitsPal(HDC hdc, int x, int y, int dx, int dy)
  1526. {
  1527.     SetDIBits(hdc, hbmApp, 0, bm.bmHeight,
  1528.             lpDibBits, (LPBITMAPINFO)&biPal, DIB_PAL_COLORS);
  1529. }
  1530.  
  1531. void DoSetDIBitsRgb(HDC hdc, int x, int y, int dx, int dy)
  1532. {
  1533.     SetDIBits(hdc, hbmApp, 0, bm.bmHeight,
  1534.             lpDibBits, (LPBITMAPINFO)&biRgb, DIB_RGB_COLORS);
  1535. }
  1536.  
  1537. void DoGetDIBitsPal(HDC hdc, int x, int y, int dx, int dy)
  1538. {
  1539. ////SelectObject(hdcApp, hbmMono);
  1540.     GetDIBits(hdc, hbmApp, 0, bm.bmHeight,
  1541.             lpDibBits, (LPBITMAPINFO)&biPal, DIB_PAL_COLORS);
  1542. ////SelectObject(hdcApp, hbmApp);
  1543. }
  1544.  
  1545. void DoGetDIBitsRgb(HDC hdc, int x, int y, int dx, int dy)
  1546. {
  1547. ////SelectObject(hdcApp, hbmMono);
  1548.     GetDIBits(hdc, hbmApp, 0, bm.bmHeight,
  1549.             lpDibBits, (LPBITMAPINFO)&biRgb, DIB_RGB_COLORS);
  1550. ////SelectObject(hdcApp, hbmApp);
  1551. }
  1552.  
  1553. #ifndef WIN32
  1554. void DrawCOPYBLT(HDC hdc, int x, int y, int dx, int dy)
  1555. {
  1556.     copy_8_8(lpBitmapBits, 0, bm.bmWidthBytes,
  1557.              lpBitmapBits, OffsetScan0, -(int)bm.bmWidthBytes,
  1558.              bm.bmWidth, bm.bmHeight, BitmapTranslate);
  1559.  
  1560.     SetBitmapBits(hbmApp, SizeImage, lpBitmapBits);
  1561.  
  1562.     StretchBlt(hdc, x, y, dx, dy,
  1563.         hdcApp, 0, 0,
  1564.         bm.bmWidth, bm.bmHeight,
  1565.         SRCCOPY);
  1566. }
  1567.  
  1568. void DrawXLATBLT(HDC hdc, int x, int y, int dx, int dy)
  1569. {
  1570.     convert_8_8(lpBitmapBits, 0, bm.bmWidthBytes,
  1571.                 lpBitmapBits, OffsetScan0, -(int)bm.bmWidthBytes,
  1572.                 bm.bmWidth, bm.bmHeight, BitmapTranslate);
  1573.  
  1574.     SetBitmapBits(hbmApp, SizeImage, lpBitmapBits);
  1575.  
  1576.     StretchBlt(hdc, x, y, dx, dy,
  1577.         hdcApp, 0, 0,
  1578.         bm.bmWidth, bm.bmHeight,
  1579.         SRCCOPY);
  1580. }
  1581. #endif
  1582.  
  1583. //
  1584. // create a rainbow palette
  1585. //
  1586. HPALETTE CreateColorPalette(int nr, int ng, int nb)
  1587. {
  1588.     LOGPALETTE          *ppal;
  1589.     PALETTEENTRY        *ppe;
  1590.     HPALETTE            hpal = NULL;
  1591.     WORD                nNumColors;
  1592.     int                 r,g,b;
  1593.  
  1594.     nNumColors = nr*ng*nb;
  1595.     ppal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
  1596.  
  1597.     if (!ppal)
  1598.         return NULL;
  1599.  
  1600.     ppal->palNumEntries = nNumColors;
  1601.     ppal->palVersion    = 0x300;
  1602.  
  1603.     ppe = ppal->palPalEntry;
  1604.  
  1605.     for (r=0; r<nr; r++)
  1606.         for (g=0; g<ng; g++)
  1607.             for (b=0; b<nb; b++)
  1608.             {
  1609.                 ppe->peRed   = (BYTE)(r * 255 / (nr-1));
  1610.                 ppe->peGreen = (BYTE)(g * 255 / (ng-1));
  1611.                 ppe->peBlue  = (BYTE)(b * 255 / (nb-1));
  1612.                 ppe->peFlags = (BYTE)0;
  1613.                 ppe++;
  1614.             }
  1615.  
  1616.     hpal = CreatePalette(ppal);
  1617.     LocalFree((HANDLE)ppal);
  1618.     return hpal;
  1619. }
  1620.  
  1621. #define RLE_ESCAPE  0
  1622. #define RLE_EOL     0
  1623. #define RLE_EOF     1
  1624. #define RLE_JMP     2
  1625. #define RLE_RUN     3
  1626.  
  1627. #define GEN_EOL(p) { \
  1628.     *(p)++ = RLE_ESCAPE; \
  1629.     *(p)++ = RLE_EOL; }
  1630.  
  1631. #define GEN_EOF(p) { \
  1632.     *(p)++ = RLE_ESCAPE; \
  1633.     *(p)++ = RLE_EOF; }
  1634.  
  1635. #define GEN_RUN(p,cnt,b) if (cnt > 0) { \
  1636.     *(p)++ = (BYTE)(cnt); \
  1637.     *(p)++ = (BYTE)(b); }
  1638.  
  1639. static PDIB MakeDib(int bits, int dx, int dy, UINT type)
  1640. {
  1641.     int         i ;
  1642.     int         x ;
  1643.     int         y ;
  1644.     LPBITMAPINFOHEADER lpbi;
  1645.     DWORD       dwSizeImage;
  1646.     BYTE _huge *pb;
  1647.     DWORD FAR  *pdw;
  1648.  
  1649.     dwSizeImage = abs(dy)*(DWORD)((dx*bits/8+3)&~3);
  1650.  
  1651.     lpbi = (LPBITMAPINFOHEADER)GlobalAllocPtr(GHND,sizeof(BITMAPINFOHEADER)+dwSizeImage + 1024);
  1652.  
  1653.     if (lpbi == NULL)
  1654.         return NULL;
  1655.  
  1656.     lpbi->biSize            = sizeof(BITMAPINFOHEADER) ;
  1657.     lpbi->biWidth           = dx;
  1658.     lpbi->biHeight          = dy;
  1659.     lpbi->biPlanes          = 1;
  1660.     lpbi->biBitCount        = bits ;
  1661.     lpbi->biCompression     = type >= BI_BITFIELDS ? BI_BITFIELDS : type;
  1662.     lpbi->biSizeImage       = dwSizeImage;
  1663.     lpbi->biXPelsPerMeter   = 0 ;
  1664.     lpbi->biYPelsPerMeter   = 0 ;
  1665.     lpbi->biClrUsed         = 0 ;
  1666.     lpbi->biClrImportant    = 0 ;
  1667.  
  1668.     dy = abs(dy);
  1669.  
  1670.     if (bits == 4)
  1671.         lpbi->biClrUsed = 16;
  1672.  
  1673.     else if (bits == 8)
  1674.         lpbi->biClrUsed = 256;
  1675.  
  1676.     else if (type >= BI_BITFIELDS)
  1677. //      lpbi->biClrUsed = 3;
  1678.         lpbi->biClrUsed = 0;
  1679.  
  1680.     pdw = (DWORD FAR *)((LPBYTE)lpbi+(int)lpbi->biSize);
  1681.     pb = (BYTE _huge *)DibPtr(lpbi);
  1682.  
  1683.     switch (type)
  1684.     {
  1685.         case BI_RLE8:
  1686.         case BI_RLE4:
  1687.         case 0:
  1688.             if (bits == 1)
  1689.             {
  1690.                 *pdw++ = 0x00000000;    // 0000  black
  1691.                 *pdw++ = 0x00FFFFFF;    // 1111  white
  1692.             }
  1693.  
  1694.             if (bits == 4)
  1695.             {
  1696. #if 0
  1697.                 *pdw++ = 0x00000000;    // 0000  black
  1698.                 *pdw++ = 0x00800000;    // 0001  dark red
  1699.                 *pdw++ = 0x00008000;    // 0010  dark green
  1700.                 *pdw++ = 0x00808000;    // 0011  mustard
  1701.                 *pdw++ = 0x00000080;    // 0100  dark blue
  1702.                 *pdw++ = 0x00800080;    // 0101  purple
  1703.                 *pdw++ = 0x00008080;    // 0110  dark turquoise
  1704.                 *pdw++ = 0x00C0C0C0;    // 1000  gray
  1705.                 *pdw++ = 0x00808080;    // 0111  dark gray
  1706.                 *pdw++ = 0x00FF0000;    // 1001  red
  1707.                 *pdw++ = 0x0000FF00;    // 1010  green
  1708.                 *pdw++ = 0x00FFFF00;    // 1011  yellow
  1709.                 *pdw++ = 0x000000FF;    // 1100  blue
  1710.                 *pdw++ = 0x00FF00FF;    // 1101  pink (magenta)
  1711.                 *pdw++ = 0x0000FFFF;    // 1110  cyan
  1712.                 *pdw++ = 0x00FFFFFF;    // 1111  white
  1713. #else
  1714.                 for (i=0; i<16; i++)
  1715.                     *pdw++ = RGB(0,0,i*255/15);
  1716. #endif
  1717.             }
  1718.  
  1719.             if (bits == 8)
  1720.             {
  1721.                 for (i=0; i<256; i++)
  1722.                     *pdw++ = RGB(i,0,0);
  1723.             }
  1724.             break;
  1725.  
  1726.         case DIB_TYPE_RGB:
  1727.             *pdw++ = 0x0000FF;
  1728.             *pdw++ = 0x00FF00;
  1729.             *pdw++ = 0xFF0000;
  1730.             break;
  1731.  
  1732.         case DIB_TYPE_BGR:
  1733.             *pdw++ = 0xFF0000;
  1734.             *pdw++ = 0x00FF00;
  1735.             *pdw++ = 0x0000FF;
  1736.             break;
  1737.  
  1738.         case DIB_TYPE_565:
  1739.             *pdw++ = 0xF800;        // make a 565 DIB
  1740.             *pdw++ = 0x07E0;
  1741.             *pdw++ = 0x001F;
  1742.             break;
  1743.  
  1744.         case DIB_TYPE_555:
  1745.             *pdw++ = 0x7C00;        // make a 555 DIB
  1746.             *pdw++ = 0x03E0;
  1747.             *pdw++ = 0x001F;
  1748.             break;
  1749.     }
  1750.  
  1751.     if (bits == 1)
  1752.     {
  1753.         for (y=0; y<dy; y++)
  1754.             for (x=0; x<dx; x += 8)
  1755.             {
  1756.                 if (y & 1)
  1757.                     *pb++ = 0xF0;
  1758.                 else
  1759.                     *pb++ = 0x0F;
  1760.             }
  1761.     }
  1762.     else if (bits == 4)
  1763.     {
  1764.         for (y=0; y<dy; y++)
  1765.             for (x=0; x<dx; x += 2)
  1766.             {
  1767.                 i = ((x / (dx / 4)) + 4 * (y / (dy / 4)));
  1768.                 i += i * 16;
  1769.                 *pb++ = i;
  1770.             }
  1771.     }
  1772.     else if (bits == 8)
  1773.     {
  1774.         for (y=0; y<dy; y++)
  1775.             for (x=0; x<dx; x++)
  1776.             {
  1777.                 i = (int)((DWORD)(UINT)y * 255u / (dy-1));
  1778.                 *pb++ = i;
  1779.             }
  1780.  
  1781.     }
  1782.     else if (bits == 16)
  1783.     {
  1784.         for (y=0; y<dy; y++)
  1785.             for (x=0; x<dx; x++)
  1786.             {           
  1787.                 *pb++ = (BYTE) ((UINT)y * 31 / (dy-1));
  1788.  
  1789.                 if (type == DIB_TYPE_565)
  1790.                     *pb++ = (BYTE)(((UINT)x * 31 / (dx-1)) << 3);
  1791.                 else
  1792.                     *pb++ = (BYTE)(((UINT)x * 31 / (dx-1)) << 2);
  1793.             }
  1794.     }
  1795.     else if (bits == 24)
  1796.     {
  1797.         for (y=0; y<dy; y++)
  1798.             for (x=0; x<dx; x++)
  1799.             {
  1800.                 *pb++ = (BYTE) ((DWORD)(UINT)y * 255u / (dy-1));
  1801.                 *pb++ = (BYTE)~((DWORD)(UINT)x * 255u / (dx-1));
  1802.                 *pb++ = (BYTE) ((DWORD)(UINT)x * 255u / (dx-1));
  1803.             }
  1804.     }
  1805.     else if (bits == 32)
  1806.     {
  1807.         for (y=0; y<dy; y++)
  1808.             for (x=0; x<dx; x++)
  1809.             {
  1810.                 *pb++ = (BYTE)~((DWORD)(UINT)x * 255u / (dx-1));
  1811.                 *pb++ = (BYTE) ((DWORD)(UINT)y * 255u / (dy-1));
  1812.                 *pb++ = (BYTE) ((DWORD)(UINT)x * 255u / (dx-1));
  1813.                 *pb++ = 0;
  1814.             }
  1815.     }
  1816.     else if (bits == 4 && type == BI_RLE4)
  1817.     {
  1818.         if (dx > 255) dx = 255;
  1819.         if (dy > 255) dy = 255;
  1820.  
  1821.         for (y=0; y<dy; y++)
  1822.         {
  1823.             GEN_RUN(pb, y/2, 0x22);
  1824.             GEN_RUN(pb, (dx-y)/2, 0xEE);
  1825.             GEN_EOL(pb);
  1826.         }
  1827.         GEN_EOF(pb);
  1828.     }
  1829.  
  1830.     else if (bits == 8 && type == BI_RLE8)
  1831.     {
  1832.         if (dx > 255) dx = 255;
  1833.         if (dy > 255) dy = 255;
  1834.  
  1835.         for (y=0; y<dy; y++)
  1836.         {
  1837.             GEN_RUN(pb, y, 0x22);
  1838.             GEN_RUN(pb, dx-y, 0xEE);
  1839.             GEN_EOL(pb);
  1840.         }
  1841.         GEN_EOF(pb);
  1842.     }
  1843.  
  1844.     return (PDIB)lpbi;
  1845. }
  1846.  
  1847.  
  1848. /*****************************************************************************
  1849.  *
  1850.  * dprintf() is called by the DPF macro if DEBUG is defined at compile time.
  1851.  *
  1852.  * The messages will be send to COM1: like any debug message. To
  1853.  * enable debug output, add the following to WIN.INI :
  1854.  *
  1855.  * [debug]
  1856.  * BLT=1
  1857.  *
  1858.  ****************************************************************************/
  1859.  
  1860. #ifdef DEBUG
  1861.  
  1862. #define MODNAME "BLT"
  1863.  
  1864. #ifndef WIN32
  1865.     #define lstrcatA lstrcat
  1866.     #define lstrcpyA lstrcpy
  1867.     #define lstrlenA lstrlen
  1868.     #define wvsprintfA      wvsprintf
  1869.     #define GetProfileIntA  GetProfileInt
  1870.     #define OutputDebugStringA OutputDebugString
  1871. #endif
  1872.  
  1873. #define _WINDLL
  1874. #include <stdarg.h>
  1875.  
  1876. void FAR CDECL dprintf(LPSTR szFormat, ...)
  1877. {
  1878.     char ach[128];
  1879.     va_list va;
  1880.  
  1881.     static BOOL fDebug = -1;
  1882.  
  1883.     if (fDebug == -1)
  1884.     fDebug = GetProfileIntA("Debug", MODNAME, TRUE);
  1885.  
  1886.     if (!fDebug)
  1887.         return;
  1888.  
  1889.     lstrcpyA(ach, MODNAME ": ");
  1890.     va_start(va, szFormat);
  1891.     wvsprintfA(ach+lstrlenA(ach),szFormat,(LPSTR)va);
  1892.     va_end(va);
  1893.     lstrcatA(ach, "\r\n");
  1894.  
  1895.     OutputDebugStringA(ach);
  1896. }
  1897.  
  1898. #endif
  1899.